package gloridifice.watersource.common.tile;

import gloridifice.watersource.registry.TileEntityTypesRegistry;
import net.minecraft.block.BlockState;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.server.SUpdateTileEntityPacket;
import net.minecraft.util.Direction;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.templates.FluidTank;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

public class WaterDispenserDownTile extends ModNormalTile {
    LazyOptional<FluidTank> tank = LazyOptional.of(this::createFluidHandler);
    public int capacity;
    int heightAmount;
    public WaterDispenserDownTile(int capacity) {
        super(TileEntityTypesRegistry.WATER_DISPENSER_DOWN);
        this.capacity = capacity;
    }

    public LazyOptional<FluidTank> getTank() {
        return tank;
    }

    @Nonnull
    @Override
    public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
        if (cap == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY){return tank.cast();}
        return LazyOptional.empty();
    }

    @Override
    public CompoundNBT getUpdateTag() {
        return this.write(new CompoundNBT());
    }

    @Override
    public void onDataPacket(NetworkManager net, SUpdateTileEntityPacket pkt) {
        this.read(world.getBlockState(pkt.getPos()), pkt.getNbtCompound());
    }

    @Nullable
    @Override
    public SUpdateTileEntityPacket getUpdatePacket() {
        CompoundNBT nbtTag = new CompoundNBT();
        this.write(nbtTag);
        return new SUpdateTileEntityPacket(getPos(), 1, nbtTag);
    }

    @Override
    public void read(BlockState state, CompoundNBT compoundNBT) {
        super.read(state, compoundNBT);
        tank.ifPresent(fluidTank -> fluidTank.readFromNBT(compoundNBT.getCompound("tank")));
    }
    @Override
    public CompoundNBT write(CompoundNBT compoundNBT) {
        tank.ifPresent(fluidTank -> compoundNBT.put("tank", fluidTank.writeToNBT(new CompoundNBT())));
        return super.write(compoundNBT);
    }


    private FluidTank createFluidHandler() {
        return new FluidTank(capacity) {
            @Override
            protected void onContentsChanged() {
                WaterDispenserDownTile.this.refresh();
                WaterDispenserDownTile.this.markDirty();
                super.onContentsChanged();
            }

            @Override
            public boolean isFluidValid(FluidStack stack) {
                return !stack.getFluid().getAttributes().isLighterThanAir() && stack.getFluid().getAttributes().getTemperature() < 500;
            }
        };
    }

    public int getFluidAmount()
    {
        return this.tank.orElse(null).getFluidAmount();
    }

    private void updateHeight()
    {
        if (this.getWorld() != null && this.getWorld().isRemote)
        {
            if (heightAmount > this.getFluidAmount())
            {
                heightAmount -= Math.max(1, (heightAmount - this.getFluidAmount()) / 10);
            }
            else if (heightAmount < this.getFluidAmount())
            {
                heightAmount += Math.max(1, (this.getFluidAmount() - heightAmount) / 10);
            }
        }
    }

    public float getHeight()
    {
        updateHeight();
        return 0.75F * this.heightAmount / capacity;
    }
}
